package bll

import (
	"context"
	"manager/client/grpc"
	"proto/dto"

	"manager/event"
	"manager/model"
	"manager/model/entity"
	"manager/store"
	"manager/store/postgres"
	"time"

	"manager/auth"
)

type message struct {
	iMessage store.IMessage
}

var Message = &message{
	iMessage: postgres.Message,
}

func (a *message) init() func() {
	return func() {}
}

func (a *message) onEvent(*event.Data) {}

// Create 创建
func (a *message) Create(ctx context.Context, in *model.MessageCreateRequest) error {
	var (
		err error
	)

	// 获取用户Id
	in.UserId, _ = auth.ContextUserID(ctx)

	// 构建创建现场数据
	c := buildMessage(in)
	id, err := a.iMessage.Create(ctx, c)
	if err != nil {
		return err
	}

	// 发送消息
	// 是否全部用户
	var userIds []int64
	isAllUser := in.PushRange == 0
	if isAllUser {
		rsp, _ := grpc.UCmd.AllUserIds(ctx, &dto.AllUserIdsRequest{})
		if rsp != nil && len(rsp.Ids) > 0 {
			userIds = append(userIds, rsp.Ids...)
		}
	} else {
		userIds = append(userIds, in.UserIds...)
	}

	// 发送消息
	var batchData []*entity.MessageNotify
	for i := 0; i < len(userIds); i++ {
		batchData = append(batchData, &entity.MessageNotify{
			MessageType: 3,
			Title:       c.Title,
			Content:     c.Content,
			UserId:      userIds[i],
			CreatedAt:   time.Now().Unix(),
			UpdatedAt:   time.Now().Unix(),
			RelationId:  id,
		})
	}

	// 批量创建
	err = postgres.GetDB(ctx).CreateInBatches(batchData, len(batchData)).Error
	return err
}

// Update 更新
func (a *message) Update(ctx context.Context, in *model.MessageUpdateRequest) error {
	var (
		dict = make(map[string]interface{})
	)

	updateAt := time.Now().Unix()
	in.UpdatedAt = &updateAt

	if in.UserId != nil {
		dict["user_id"] = in.UserId
	}

	if in.PushType != nil {
		dict["push_type"] = in.PushType
	}

	if in.PushRange != nil {
		dict["push_range"] = in.PushRange
	}

	if in.PushTime != nil {
		dict["push_time"] = in.PushTime
	}

	if in.Title != nil {
		dict["title"] = in.Title
	}

	if in.Content != nil {
		dict["content"] = in.Content
	}

	if in.Delay != nil {
		dict["delay"] = in.Delay
	}

	if in.DeletedAt != nil {
		dict["deleted_at"] = in.DeletedAt
	}

	if in.UpdatedAt != nil {
		dict["updated_at"] = in.UpdatedAt
	}

	// do other update here

	return a.iMessage.Update(ctx, in.Id, dict)
}

// Delete 删除
func (a *message) Delete(ctx context.Context, in *model.MessageDeleteRequest) error {
	return a.iMessage.Delete(ctx, in.Id)
}

// List 列表查询
func (a *message) List(ctx context.Context, in *model.MessageListRequest) (*model.MessageListResponse, error) {
	var (
		err   error
		total int
		list  []*entity.Message
		out   = &model.MessageListResponse{}
	)

	if total, list, err = a.iMessage.List(ctx, in); err != nil {
		return nil, err
	}

	out.Total = total
	out.List = model.MessagesEntityToDto(list)

	return out, nil
}

// Find 列表查询
func (a *message) Find(ctx context.Context, in *model.MessageInfoRequest) (*model.MessageInfo, error) {
	var (
		err  error
		data *entity.Message
		out  = &model.MessageInfo{}
	)

	if data, err = a.iMessage.Find(ctx, in); err != nil {
		return nil, err
	}

	out = model.MessageEntityToDto(data)
	return out, nil
}

// buildMessage 构建创建数据现场
func buildMessage(in *model.MessageCreateRequest) *entity.Message {
	// todo: check the entity is required
	return &entity.Message{

		UserId: in.UserId,

		PushType: in.PushType,

		PushRange: in.PushRange,

		PushTime: int(time.Now().Unix()),

		Title: in.Title,

		Content: in.Content,

		Delay: in.Delay,

		UserIds: in.UserIds,

		DeletedAt: in.DeletedAt,

		CreatedAt: time.Now().Unix(),

		UpdatedAt: time.Now().Unix(),
	}
}
